package com.lazi.june.web.json;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.NumberSerializer;

import java.io.IOException;
import java.math.BigInteger;

/**
 * desc:超出 JS 最大最小值 处理
 *
 * @author huliqian
 * @since 2025/8/22
 */
public class BigNumberSerializer extends NumberSerializer {

    /**
     * 根据 JS Number.MAX_SAFE_INTEGER 与 Number.MIN_SAFE_INTEGER 得来
     */
    private static final long MAX_SAFE_INTEGER = 9007199254740991L;
    private static final long MIN_SAFE_INTEGER = -9007199254740991L;

    /**
     * 提供实例
     */
    public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class);

    public BigNumberSerializer(Class<? extends Number> rawType) {
        super(rawType);
    }

    @Override
    public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (value == null) {
            provider.defaultSerializeNull(gen);
            return;
        }
        // Long 类型按安全范围输出，否则转字符串
        if (value instanceof Long l) {
            if (l > MIN_SAFE_INTEGER && l < MAX_SAFE_INTEGER) {
                super.serialize(value, gen, provider);
            } else {
                gen.writeString(l.toString());
            }
            return;
        }
        // BigInteger 始终转字符串，避免 JS 精度问题
        if (value instanceof BigInteger bi) {
            gen.writeString(bi.toString());
            return;
        }
        // 其他数值类型走默认逻辑
        super.serialize(value, gen, provider);
    }
}
